iT邦幫忙

2022 iThome 鐵人賽

DAY 7
0
DevOps

從認識Docker到精通系列 第 7

第七天-Multi-stage build

  • 分享至 

  • xImage
  •  

再進入docker volume之前,讓我們來看看 multi-stage dockerfile 這個寫dockerfile 的方式吧!

一樣又是getting-started這個範例...XD

Multi-stages builds

Build image 的時候,要儘量讓image的檔案大小愈小愈好,而 image 的大小和 image layer 的數量有關,每使用 RUNCOPY 等指令都會疊加新的一層 layer在舊有的 image上,故看前人編寫的dockerfile中,都可以看出使用shell tricks、或極力精簡架構、或一直刪除前一步驟的 artifacts 的習慣,這些作為都是在盡力縮小 image 的大小。

在 docker reference 中有提到,為減少映像的大小,也可以採取使用兩個Dockerfile,一個用於開發 (dockerfile.build),一個用於生產環境 (dockerfile),但要維護兩個 dockerfile,在實際上較為不理想。

若採用 Multi-stage builds,可解決以上的難處:在 multi-stage 的dockerfile 中,可以用多個 FROM 引用不同的映像(同時代表多個 stage),並在 stage 之間互相引用其他 stage 的 artifacts,藉此,可以在同一個 dockerfile 中達成開發和部署,也可以藉由移動artifact來減少映像檔的大小(只會用最後一個image,過程中使用的image的不會被納入image中)。

以上述的 getting-started 為例,在一開始使用了python:alpine 映像建立 base ,並 build 出/app/site 的 artifacts,接著用 node:12-alpine 建立 app-zip-creator build出靜態的網頁,壓縮成zip檔app.zip;在最後實際的環境使用nginx:alpine,並複製base/app/siteapp-zip-creatorapp.zip ,整份映像檔在build 的時候只會有 nginx/app/siteapp.zip三個必要的部分,不會有開發時需要的node modules等等其他在部署時非必要的檔案,整份映像檔也因此變得更輕量,部署也會更快速。

取別名

我們可以使用FROM <image> AS <alias-name> (記得去除腳括弧),幫映像取名為<alias-name>

使用其他 stage 的 artifacts

要使用其他 stage 的 artifacts 時利用 COPY --from=<image-name> <item> <item> ..便可以複製東西出來到當前的image中。

Reference

Best practices for writing Dockerfiles | Docker Documentation
Use multi-stage builds | Docker Documentation


上一篇
DockerFile-3 Recap getting-started
下一篇
Docker Volume
系列文
從認識Docker到精通30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言